﻿using BinConfig;
using JGSoft.U9CRTAPIEX.DTOs;
using JGSoft.U9CRTAPIEX.DTOs.Enum;
using JGSoft.U9CRTAPIEX.DTOs.RequestDTOs;
using JGSoft.U9CRTAPIEX.Public;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Results;
using UFIDA.U9.AP.ForAPI;
using UFIDA.U9.Base;
using UFIDA.U9.Base.FlexField.ValueSet;
using UFIDA.U9.Base.Organization;
using UFIDA.U9.Base.UOM;
using UFIDA.U9.CBO.DTOs;
using UFIDA.U9.CBO.Enums;
using UFIDA.U9.CBO.FI.UI;
using UFIDA.U9.CBO.MFG.BOM;
using UFIDA.U9.CBO.MFG.CostElement;
using UFIDA.U9.CBO.MFG.Enums;
using UFIDA.U9.CBO.MFG.PMM;
using UFIDA.U9.CBO.Pub.Controller;
using UFIDA.U9.CBO.SCM.Enums;
using UFIDA.U9.CBO.SCM.Item;
using UFIDA.U9.GL.Voucher;
using UFIDA.U9.ISV.Item.Proxy;
using UFIDA.U9.ISV.MFG.BOM.Proxy;
using UFSoft.UBF.AopFrame.Lock;
using UFSoft.UBF.Business;
using UFSoft.UBF.MVC.Common;

namespace JGSoft.U9CRTAPIEX.Controllers
{
    public class YunmaController : ApiController
    {
        private readonly string _userCode;
        private readonly string _entCode;
        private readonly string _orgCode;
        public YunmaController()
        {
            JsonConfig _config = new JsonConfig();
            _userCode = _config.SelectToken("UserCode");
            _entCode = _config.SelectToken("EntCode");
            _orgCode = _config.SelectToken("OrgCode");
        }
        /// <summary>
        /// 计量单位新增和修改
        /// </summary>
        /// <param name="para"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult<long> UomSave(UomSaveDto para)
        {
            ApiResult<long> result = new ApiResult<long>();
            LogManager.WriteLog(JsonConvert.SerializeObject(para), "YunmaRequest");
            using (BPForEngine bp = new BPForEngine())
            {
                ContextDTO tdto = new ContextDTO();
                tdto.UserCode = _userCode;//取接口传入的用户编码
                tdto.EntCode = _entCode;//取接口传入的企业编码
                tdto.CultureName = "zh-CN";//固定
                tdto.OrgCode = _orgCode;//取接口传入的组织编码
                tdto.WriteToContext();

                try
                {
                    using (ISession session = Session.Open())
                    {
                        var UOMClassCode = (int)System.Enum.Parse(typeof(ParaUOMClassEnum), para.Unit_type.Name);
                        var uomClsss = UOMClassEnum.GetFromValue(UOMClassCode);
                        //检查是否存在云码ID来区分新增和修改
                        var uom = UOM.Finder.Find($"DescFlexField.PrivateDescSeg30 = '{para.Id}'");
                        //检查系统有无预设的同Code的单位
                        var uom1 = UOM.Finder.Find($"Code = '{para.Unit_code}'");
                        var baseUom = UOM.Finder.Find($"IsBase = 1 and UOMClass = {UOMClassCode}");
                        if (uom == null && uom1 == null)
                        {
                            uom = UOM.Create();
                            uom.Code = para.Unit_code;
                            uom.Name = para.Name;
                            uom.BaseUOM = baseUom;
                            uom.UOMClass = UOMClassEnum.GetFromValue(UOMClassCode);
                            uom.DescFlexField.PrivateDescSeg30 = para.Id.ToString();
                        }
                        else
                        {
                            uom = uom ?? uom1;
                            uom.Code = para.Unit_code;
                            uom.Name = para.Name;
                            uom.BaseUOM = baseUom;
                            uom.UOMClass = UOMClassEnum.GetFromValue(UOMClassCode);
                            uom.DescFlexField.PrivateDescSeg30 = para.Id.ToString();
                        }
                        session.Commit();
                        result.Data = uom.ID;
                        return result;
                    }
                }
                catch (Exception ex)
                {
                    LogManager.WriteLog(ex.Message + "\r\n" + ex.StackTrace, "All");
                    result.ResCode = 1;
                    result.ResMsg = ex.Message;
                    return result;
                }
            }
        }
        /// <summary>
        /// 料品分类新增和修改
        /// </summary>
        /// <param name="para"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult<long> CategorySave(CategorySaveDto para)
        {
            ApiResult<long> result = new ApiResult<long>();
            LogManager.WriteLog(JsonConvert.SerializeObject(para), "YunmaRequest");
            using (BPForEngine bp = new BPForEngine())
            {
                ContextDTO tdto = new ContextDTO();
                tdto.UserCode = _userCode;//取接口传入的用户编码
                tdto.EntCode = _entCode;//取接口传入的企业编码
                tdto.CultureName = "zh-CN";//固定
                tdto.OrgCode = _orgCode;//取接口传入的组织编码
                tdto.WriteToContext();
                try
                {
                    using (ISession session = Session.Open())
                    {
                        var categorySystem = ItemCategoryType.FindByCode("10") ?? throw new Exception("编码为10的料品分类体系不存在");
                        //检查是否存在云码ID来区分新增和修改
                        var category = ItemCategory.Finder.Find($"DescFlexField.PrivateDescSeg30 = '{para.Id}'");
                        var category1 = ItemCategory.Finder.Find($"Code = '{para.category_code}'");
                        if (category == null && category1 == null)
                        {
                            category = ItemCategory.Create();
                            category.CategorySystem = categorySystem;
                            category.Code = para.category_code;
                            category.Name = para.Name;
                            category.Org = Organization.FindByCode(_orgCode);
                            category.CategoryUOM = UOM.FindByCode("PCS");
                            category.DescFlexField.PrivateDescSeg30 = para.Id.ToString();
                        }
                        else
                        {
                            category = category ?? category1;
                            category.Code = para.category_code;
                            category.Name = para.Name;
                            category.CategorySystem = categorySystem;
                            category.CategoryUOM = UOM.FindByCode("PCS");
                            category.DescFlexField.PrivateDescSeg30 = para.Id.ToString();
                        }
                        session.Commit();
                        result.Data = category.ID;
                        return result;
                    }
                }
                catch (Exception ex)
                {
                    LogManager.WriteLog(ex.Message + "\r\n" + ex.StackTrace, "All");
                    result.ResCode = 1;
                    result.ResMsg = ex.Message;
                    return result;
                }
            }
        }
        /// <summary>
        /// 料品新增和修改
        /// </summary>
        /// <param name="para"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult<long> ItemSave(ItemSaveDto para)
        {
            ApiResult<long> result = new ApiResult<long>();
            LogManager.WriteLog(JsonConvert.SerializeObject(para), "YunmaRequest");
            using (BPForEngine bp = new BPForEngine())
            {
                ContextDTO tdto = new ContextDTO();
                tdto.UserCode = _userCode;//取接口传入的用户编码
                tdto.EntCode = _entCode;//取接口传入的企业编码
                tdto.CultureName = "zh-CN";//固定
                tdto.OrgCode = _orgCode;//取接口传入的组织编码
                tdto.WriteToContext();
                string type = "", PL = "", HX1 = "", YS = "", KFLH = "", MZ = "", MTYS = "";
                if (!string.IsNullOrEmpty(para.extra_attr_value))
                {
                    var extraValue = JsonConvert.DeserializeObject<List<extra_attr_value>>(para.extra_attr_value);
                    type = extraValue.FirstOrDefault(t => t.en_attribute_name == "JCXH")?.item_name;
                    PL = extraValue.FirstOrDefault(t => t.en_attribute_name == "PL")?.item_name;
                    HX1 = extraValue.FirstOrDefault(t => t.en_attribute_name == "HX1")?.item_name;
                    YS = extraValue.FirstOrDefault(t => t.en_attribute_name == "YS")?.item_name;
                    KFLH = extraValue.FirstOrDefault(t => t.en_attribute_name == "KFLH")?.item_name;
                    MZ = extraValue.FirstOrDefault(t => t.en_attribute_name == "MZ")?.item_name;
                    MTYS = extraValue.FirstOrDefault(t => t.en_attribute_name == "MTYS(YW)")?.item_name;
                }
                try
                {
                    //值集值
                    string typeValueCode = "";
                    bool isMul = false;
                    long itemID = 0;
                    //制造件的机型字段机型字段不能为空
                    if (string.IsNullOrEmpty(HX1) && para.materiel_source.Name == "制造件")
                        throw new Exception("制造件的机型字段机型字段不能为空");
                    //添加值集值
                    if (!string.IsNullOrEmpty(HX1))
                    {
                        if (isMul == false)
                            typeValueCode = "1";
                        ValueSetDef valueSetDef = ValueSetDef.FindByCode("JX") ?? throw new Exception("未找到编码为JX的值集定义");
                        DefineValue defineValue = DefineValue.Finder.Find($"Name = '{HX1}' and ValueSetDef = {valueSetDef.ID}");
                        if (defineValue == null)
                        {
                            //自增长编号
                            var defineValues = DefineValue.Finder.FindAll($"ValueSetDef = {valueSetDef.ID}");
                            if (defineValues != null && defineValues.Count > 0 && isMul == false)
                            {
                                typeValueCode = (defineValues.Cast<DefineValue>().Max(x => Convert.ToInt32(x.Code)) + 1).ToString();
                            }
                            else
                            {
                                typeValueCode = (Convert.ToInt32(typeValueCode) + 1).ToString();
                            }
                            isMul = true;
                            using (ISession session = Session.Open())
                            {
                                defineValue = DefineValue.Create();
                                defineValue.ValueSetDef = valueSetDef;
                                defineValue.Name = HX1;
                                defineValue.Code = typeValueCode;
                                session.Commit();
                            }
                        }
                        else
                        {
                            typeValueCode = defineValue.Code;
                        }
                    }
                    if (!string.IsNullOrEmpty(type))
                    {
                        ValueSetDef valueSetDef = ValueSetDef.FindByCode("JX2") ?? throw new Exception("未找到编码为JX2的值集定义");
                        DefineValue defineValue = DefineValue.Finder.Find($"Name = '{type}' and ValueSetDef = {valueSetDef.ID}");
                        if (defineValue == null)
                        {
                            using (ISession session = Session.Open())
                            {
                                defineValue = DefineValue.Create();
                                defineValue.ValueSetDef = valueSetDef;
                                defineValue.Name = type;
                                defineValue.Code = type;
                                session.Commit();
                            }
                        }
                    }
                    //检查是否存在云码ID来区分新增和修改
                    var itemmaster = ItemMaster.Finder.Find($"DescFlexField.PrivateDescSeg30 = '{para.id}'");
                    var uom = UOM.Finder.Find($"DescFlexField.PrivateDescSeg30 = '{para.unit.Id}'") ?? throw new Exception($"未找到云码ID{para.unit.Id}对应的计量单位{para.unit.Code}");
                    //是否本身就存在Code相同的料品
                    var itemmaster1 = ItemMaster.Finder.Find($"Code = '{para.materiel_code}'");
                    if (itemmaster == null && itemmaster1 == null)
                    {
                        BatchCreateItemByDTOSRVProxy sv = new BatchCreateItemByDTOSRVProxy();
                        var svparas = new List<UFIDA.U9.ISV.Item.ItemMasterDTOData>();
                        var svpara = new UFIDA.U9.ISV.Item.ItemMasterDTOData();
                        svpara.Org = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData()
                        {
                            Code = _orgCode
                        };

                        var uomPara = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData()
                        {
                            ID = uom.ID
                        };
                        svpara.Code = para.materiel_code;
                        svpara.Name = para.materiel_name;
                        svpara.Code1 = para.old_materiel_code;
                        svpara.SPECS = para.materiel_desc;
                        svpara.ItemFormAttribute = (int)System.Enum.Parse(typeof(ParaItemAttributeEnum), para.materiel_source.Name);
                        ItemStateDefaultValue(svpara);
                        svpara.InventoryUOM = uomPara;
                        svpara.SalesUOM = uomPara;
                        svpara.PurchaseUOM = uomPara;
                        svpara.PriceUOM = uomPara;
                        svpara.ManufactureUOM = uomPara;
                        svpara.MaterialOutUOM = uomPara;
                        svpara.CostUOM = uomPara;
                        svpara.ConverRatioRule = 0;//标准转换率
                        svpara.State = 2;
                        svpara.Effective = new UFIDA.U9.Base.PropertyTypes.EffectiveData
                        {
                            IsEffective = false,
                            EffectiveDate = new DateTime(2000, 1, 1),
                            DisableDate = new DateTime(9999, 12, 31)
                        };
                        var category = ItemCategory.Finder.Find($"DescFlexField.PrivateDescSeg30 = '{para.category.Id}'") ?? throw new Exception($"未找到云码ID{para.category.Id}对应的物料分类{para.category.Code}");
                        svpara.StockCategory = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData()
                        {
                            ID = category.ID
                        };
                        //辅料：编码F开头，11位，采购件品，直接生效
                        if (svpara.Code.StartsWith("F") && svpara.Code.Length == 11 && svpara.ItemFormAttribute == 9)
                        {
                            svpara.Effective.IsEffective = true;
                            svpara.IsSalesEnable = true;
                            svpara.IsPurchaseEnable = true;
                            svpara.IsOutsideOperationEnable = true;
                            svpara.IsMRPEnable = true;
                            svpara.IsBOMEnable = true;
                            svpara.IsVMIEnable = true;
                        }

                        //料品库存信息DTO
                        var m_invInfo = new UFIDA.U9.ISV.Item.ItemInvInfoDTOData();
                        m_invInfo.InventoryPlanningMethod = 4;// MRP规划
                        svpara.InventoryInfo = m_invInfo;
                        //料品采购信息DTO
                        var m_purchaseInfo = new UFIDA.U9.ISV.Item.ItemPurchaseInfoDTOData
                        {
                            PurchaseQuotaMode = 4,
                            QuotaSupplier = 1,
                            PriceSource = 0,
                            ReceiptMode = 0,
                            ReceiptModeAllowModify = true,
                            ReceiptRule = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData()
                            {
                                Code = "10"
                            },
                            ReceiptType = 0
                        };
                        svpara.PurchaseInfo = m_purchaseInfo;
                        //料品销售信息DTO
                        var m_saleInfo = new UFIDA.U9.ISV.Item.ItemSaleInfoDTOData
                        {
                            LimitPriceMode = 0,//定义绝对价格
                            SupplySource = 4//当前组织
                        };
                        svpara.SaleInfo = m_saleInfo;
                        //料品生产信息DTO
                        var m_mfgInfo = new UFIDA.U9.ISV.Item.ItemMFGInfoDTOData()
                        {
                            BuildShrinkageRate = 1M,//产出率
                            IsSueOverType = -1
                        };
                        svpara.MfgInfo = m_mfgInfo;
                        //料品MRP（计划）信息DTO
                        var m_mrpInfo = new UFIDA.U9.ISV.Item.ItemMRPInfoDTOData
                        {
                            MRPPlanningType = 1,
                            ForecastContorlType = 1
                        };
                        svpara.MrpInfo = m_mrpInfo;
                        //料品质量信息DTO
                        var m_inspectionInfo = new UFIDA.U9.ISV.Item.ItemInspectionInfoDTOData();
                        //m_inspectionInfo.ReceiptInspectRule = 1001007098596394;//APIQCSchema001 API质检方案001
                        svpara.InspectionInfo = m_inspectionInfo;
                        //料品厂牌信息DTO
                        //svpara.IsTrademark = true;
                        var m_tradeMark = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData() { };
                        svpara.TradeMark = m_tradeMark;

                        svpara.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegmentsData()
                        {
                            PrivateDescSeg30 = para.id.ToString(),
                            PubDescSeg22 = typeValueCode,
                            PubDescSeg26 = type,
                            PrivateDescSeg3 = PL,
                            PrivateDescSeg5 = type,
                            PrivateDescSeg6 = KFLH,
                            PrivateDescSeg7 = para.unit_weight.ToString(),
                            PrivateDescSeg8 = MZ,
                            PrivateDescSeg9 = para.unit_length.ToString(),
                            PrivateDescSeg11 = para.unit_width.ToString(),
                            PrivateDescSeg12 = para.unit_height.ToString(),
                            PrivateDescSeg13 = MTYS
                        };
                        svparas.Add(svpara);
                        sv.ItemMasterDTOs = svparas;
                        var svResult = sv.Do();
                        itemID = svResult[0].ID;
                    }
                    else
                    {
                        itemmaster = itemmaster ?? itemmaster1;
                        using (ISession session = Session.Open())
                        {
                            itemmaster.Code = para.materiel_code;
                            itemmaster.Name = para.materiel_name;
                            itemmaster.Code1 = para.old_materiel_code;
                            itemmaster.SPECS = para.materiel_desc;
                            //itemmaster.ItemFormAttribute = item.ItemFormAttribute;
                            itemmaster.InventoryUOM = uom;
                            itemmaster.InventorySecondUOM = uom;
                            itemmaster.SalesUOM = uom;
                            itemmaster.PurchaseUOM = uom;
                            itemmaster.PriceUOM = uom;
                            itemmaster.ManufactureUOM = uom;
                            itemmaster.MaterialOutUOM = uom;
                            itemmaster.CostUOM = uom;
                            itemmaster.DescFlexField.PubDescSeg22 = typeValueCode;
                            itemmaster.DescFlexField.PubDescSeg26 = type;
                            itemmaster.DescFlexField.PrivateDescSeg3 = PL;
                            itemmaster.DescFlexField.PrivateDescSeg5 = type;
                            itemmaster.DescFlexField.PrivateDescSeg30 = para.id.ToString();
                            itemmaster.DescFlexField.PrivateDescSeg1 = YS;
                            itemmaster.DescFlexField.PrivateDescSeg6 = KFLH;
                            itemmaster.DescFlexField.PrivateDescSeg7 = para.unit_weight.ToString();
                            itemmaster.DescFlexField.PrivateDescSeg8 = MZ;
                            itemmaster.DescFlexField.PrivateDescSeg9 = para.unit_length.ToString();
                            itemmaster.DescFlexField.PrivateDescSeg11 = para.unit_width.ToString();
                            itemmaster.DescFlexField.PrivateDescSeg12 = para.unit_height.ToString();
                            itemmaster.DescFlexField.PrivateDescSeg13 = MTYS;
                            //料品失效
                            //if (Convert.ToBoolean(para.materiel_status) == false)
                            //{
                            //    itemmaster.Effective.IsEffective = false;
                            //}
                            session.Commit();
                            itemID = itemmaster.ID;
                        }
                    }
                    result.Data = itemID;
                    return result;
                }
                catch (Exception ex)
                {
                    LogManager.WriteLog(ex.Message + "\r\n" + ex.StackTrace, "All");
                    result.ResCode = 1;
                    result.ResMsg = ex.Message;
                    return result;
                }
            }
        }
        /// <summary>
        /// BOM新增和修改
        /// </summary>
        /// <param name="para"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult<long> BOMSave(BOMSaveDto para)
        {
            ApiResult<long> result = new ApiResult<long>();
            LogManager.WriteLog(JsonConvert.SerializeObject(para), "YunmaRequest");
            using (BPForEngine bp = new BPForEngine())
            {
                ContextDTO tdto = new ContextDTO();
                tdto.UserCode = _userCode;//取接口传入的用户编码
                tdto.EntCode = _entCode;//取接口传入的企业编码
                tdto.CultureName = "zh-CN";//固定
                tdto.OrgCode = _orgCode;//取接口传入的组织编码
                tdto.WriteToContext();

                try
                {
                    long bomID = 0;
                    CreateBOMSvProxy sv = new CreateBOMSvProxy();
                    var svparas = new List<UFIDA.U9.ISV.MFG.BOM.BOMMasterDTO4CreateSvData>();
                    var itemmaster = ItemMaster.Finder.Find($"DescFlexField.PrivateDescSeg30 = '{para.materiel_id}'") ?? throw new Exception($"未找到云码ID{para.materiel_id}对应的料品{para.materiel_code}");
                    BOMMaster bommster = BOMMaster.Finder.Find($"DescFlexField.PrivateDescSeg30 = '{para.id}'");
                    BOMMaster bommster1 = BOMMaster.Finder.Find($"itemmaster = '{itemmaster.ID}'");

                    var svpara = new UFIDA.U9.ISV.MFG.BOM.BOMMasterDTO4CreateSvData
                    {
                        ItemMaster = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData() { ID = itemmaster.ID },
                        BOMType = 0,
                        Org = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData() { Code = _orgCode },
                        BOMVersionCode = "A0",
                        AlternateType = 0,
                        Lot = 1,
                        IsPrimaryLot = true,
                        ProductUOM = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData { ID = itemmaster.InventoryUOM.ID },
                        //OwnerOrg = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData() { ID = Context.LoginOrg.ID },
                        EffectiveDate = new DateTime(2000, 1, 1),
                        DisableDate = new DateTime(9999, 12, 31),
                        Status = 2,
                        DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegmentsData() { PrivateDescSeg30 = para.id.ToString() },
                    };
                    var comps = new List<UFIDA.U9.ISV.MFG.BOM.BOMComponentDTO4CreateSvData>();
                    //提前查出所有子项
                    string yunmaIDList = string.Join(",", para.bomDetailSyncDataVOS.Select(t => $"'{t.materiel_id}'"));
                    //云码空BOM处理
                    if (para.bomDetailSyncDataVOS.Count == 0)
                    {
                        //ERP未创建
                        if (bommster == null && bommster1 == null)
                        {
                            result.ResCode = 0;
                            result.ResMsg = "BOM子项不能为空";
                            return result;
                        }
                        //ERP已创建，弃审并删除BOM
                        else
                        {
                            bommster = bommster ?? bommster1;
                            using (ISession session = Session.Open())
                            {
                                bommster.Status = MFGDocStatusEnum.Opened;
                                bommster.StatusUser = UFIDA.U9.Base.UserRole.User.Finder.FindByID(Context.LoginUserID);
                                bommster.StatusTime = Context.LoginDate;
                                bommster.IsNeedUpdateWIP = false;
                                bommster.NeedSetDefaultValueAndValidate = false;
                                session.Commit();
                            }
                            using (ISession session = Session.Open())
                            {
                                bommster.Remove();
                                session.Commit();
                            }
                            result.ResCode = 0;
                            return result;
                        }
                    }
                    var compItemList = ItemMaster.Finder.FindAll($"DescFlexField.PrivateDescSeg30 in ({yunmaIDList})").Cast<ItemMaster>().ToList();
                    StringBuilder sb = new StringBuilder();
                    //料品生效性检查
                    foreach (var item in compItemList)
                    {
                        if (item.Effective.IsEffective == false)
                            sb.Append($"{item.Code},");
                    }
                    if (sb.Length > 0)
                    {
                        sb.Append("料品未生效");
                        result.ResCode = 1;
                        result.ResMsg = sb.ToString();
                        LogManager.WriteLog(sb.ToString(), "All");
                        return result;
                    }
                    foreach (var comp in para.bomDetailSyncDataVOS)
                    {
                        //var compItem = ItemMaster.Finder.Find($"DescFlexField.PrivateDescSeg30 = '{comp.materiel_id}'") ?? throw new Exception($"未找到云码ID{comp.materiel_id}对应的料品");
                        var compItem = compItemList.FirstOrDefault(t => t.DescFlexField.PrivateDescSeg30 == comp.materiel_id.ToString()) ?? throw new Exception($"未找到云码ID{comp.materiel_id}对应的料品{comp.materiel_code}");
                        var comppara = new UFIDA.U9.ISV.MFG.BOM.BOMComponentDTO4CreateSvData
                        {
                            ItemMaster = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData() { ID = compItem.ID },
                            UsageQty = comp.single_num,
                            UsageQtyType = 1,
                            ComponentType = 0,
                            Sequence = comp.serial_number * 10,
                            ParentQty = 1,
                            IssueUOM = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData() { ID = compItem.InventoryUOM.ID },
                            ScrapType = 0,
                            FixedScrap = 0,
                            Scrap = 0,
                            PlanPercent = 0,
                            IsEffective = true,
                            IssueStyle = 0,
                            SupplyStyle = 0,
                            ConsignProcessItemSrc = 2,
                            IssueOrg = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData() { Code = _orgCode },
                            SetChkAtComplete = true,
                            RCVApproved = true,
                            IsWholeSetIssue = true,
                            SubstituteStyle = 0,
                            SubSeq = 0,
                            StandardMaterialScale = 0,
                            FixedMaterialNum = 0,
                            LeadTimeOffSet = 0,
                            MinSelectedQty = 1,
                            MaxSelectedQty = 1,
                            IsCharge = true,
                            CostElement = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData() { Code = "No101" },
                            CostPercent = 0,
                            TimeUOM = new UFIDA.U9.CBO.Pub.Controller.CommonArchiveDataDTOData() { Code = "DAY" },
                            //DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegmentsData() { PrivateDescSeg30 = comp.CompID.ToString(), PubDescSeg9 = comp.PositionName, PubDescSeg8 = comp.PartName, PubDescSeg20 = comp.PartCode },
                            DescFlexField_PrivateDescSeg30 = comp.bom_detail_id.ToString(),
                            DescFlexField_PubDescSeg9 = comp.position_name,
                            DescFlexField_PubDescSeg8 = comp.part_name,
                            DescFlexField_PubDescSeg20 = comp.part_code,
                            OperationNum = "10",
                            Remark = comp.remark
                        };
                        comps.Add(comppara);
                    }
                    svpara.BOMComponents = comps;
                    svparas.Add(svpara);
                    if (bommster == null && bommster1 == null)
                    {

                        sv.BOMMasterDTOList = svparas;
                        var svresult = sv.Do();
                        bomID = svresult[0].BOMMasterDTO.BOMMasterID;
                    }
                    else//修改BOM子项
                    {
                        bommster = bommster ?? bommster1;
                        using (ISession session = Session.Open())
                        {
                            List<BOMComponent> itemsToRemove = new List<BOMComponent>();
                            foreach (var bomcomponent in bommster.BOMComponents)
                            {
                                if (!svpara.BOMComponents.Any(t => t.ItemMaster.ID == bomcomponent.ItemMaster.ID && t.DescFlexField_PubDescSeg9 == bomcomponent.DescFlexField.PubDescSeg9 && t.DescFlexField_PubDescSeg20 == bomcomponent.DescFlexField.PubDescSeg20))
                                    itemsToRemove.Add(bomcomponent);
                            }
                            foreach (var item in itemsToRemove)
                            {
                                bommster.BOMComponents.Remove(item);
                            }
                            foreach (var comp in svpara.BOMComponents)
                            {
                                var compItem = compItemList.FirstOrDefault(t => t.ID == comp.ItemMaster.ID);
                                var BOMComponents = bommster.BOMComponents.Cast<BOMComponent>().ToList();
                                BOMComponent bOMComponent1 = BOMComponents.FirstOrDefault(t => t.ItemMaster.ID == comp.ItemMaster.ID && t.DescFlexField.PubDescSeg9 == comp.DescFlexField_PubDescSeg9 && t.DescFlexField.PubDescSeg20 == comp.DescFlexField_PubDescSeg20);
                                if (bOMComponent1 == null)
                                {
                                    bOMComponent1 = BOMComponent.Create(bommster);
                                    //var comit = svparas[0].BOMComponents[0];
                                    //var compItem = ItemMaster.Finder.FindByID(comp.ItemMaster.ID);
                                    bOMComponent1.ItemMaster = compItem;
                                    bOMComponent1.UsageQty = comp.UsageQty;
                                    bOMComponent1.UsageQtyType = UsageQuantityTypeEnum.Variable;
                                    bOMComponent1.ComponentType = ComponentTypeEnum.StandardComp;
                                    bOMComponent1.Sequence = comp.Sequence;
                                    bOMComponent1.ParentQty = comp.ParentQty;
                                    bOMComponent1.IssueUOM = compItem.InventoryUOM;
                                    bOMComponent1.ScrapType = ScrapTypeEnum.SingleScrap;
                                    bOMComponent1.FixedScrap = comp.FixedScrap;
                                    bOMComponent1.Scrap = comp.Scrap;
                                    bOMComponent1.IsEffective = comp.IsEffective;
                                    bOMComponent1.IssueStyle = IssueStyleEnum.Push;
                                    bOMComponent1.SupplyStyle = SupplyStyleEnum.Org;
                                    bOMComponent1.ConsignProcessItemSrc = ConsignProcessItemSrcEnum.IssuedByConsignee;
                                    bOMComponent1.IssueOrg = Organization.FindByCode(_orgCode);
                                    bOMComponent1.SetChkAtComplete = comp.SetChkAtComplete;
                                    bOMComponent1.RCVApproved = comp.RCVApproved;
                                    bOMComponent1.IsWholeSetIssue = comp.IsWholeSetIssue;
                                    bOMComponent1.SubstituteStyle = SubstituteStyleEnum.None;
                                    bOMComponent1.SubSeq = comp.SubSeq;
                                    bOMComponent1.StandardMaterialScale = comp.StandardMaterialScale;
                                    bOMComponent1.FixedMaterialNum = comp.FixedMaterialNum;
                                    bOMComponent1.LeadTimeOffSet = comp.LeadTimeOffSet;
                                    bOMComponent1.MinSelectedQty = comp.MinSelectedQty;
                                    bOMComponent1.MaxSelectedQty = comp.MaxSelectedQty;
                                    bOMComponent1.IsCharge = comp.IsCharge;
                                    CostElement costElement = CostElement.Finder.Find($"Code = '{comp.CostElement.Code}'");
                                    bOMComponent1.CostElement = costElement;
                                    bOMComponent1.CostPercent = comp.CostPercent;
                                    UOM TimeUOM = UOM.Finder.Find($"Code = '{comp.TimeUOM.Code}'");
                                    bOMComponent1.TimeUOM = TimeUOM;
                                    bOMComponent1.OperationNum = comp.OperationNum;
                                    bOMComponent1.Remark = comp.Remark;
                                    bOMComponent1.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments
                                    {
                                        PrivateDescSeg30 = comp.DescFlexField_PrivateDescSeg30,
                                        PubDescSeg9 = comp.DescFlexField_PubDescSeg9,
                                        PubDescSeg8 = comp.DescFlexField_PubDescSeg8,
                                        PubDescSeg20 = comp.DescFlexField_PubDescSeg20
                                    };
                                }
                                else
                                {
                                    bOMComponent1.UsageQty = comp.UsageQty;
                                    bOMComponent1.Sequence = comp.Sequence;
                                    bOMComponent1.IssueUOM = compItem.InventoryUOM;
                                    bOMComponent1.Remark = comp.Remark;
                                    bOMComponent1.DescFlexField.PrivateDescSeg30 = comp.DescFlexField_PrivateDescSeg30;
                                    bOMComponent1.DescFlexField.PubDescSeg8 = comp.DescFlexField_PubDescSeg8;
                                    bOMComponent1.DescFlexField.PubDescSeg20 = comp.DescFlexField_PubDescSeg20;
                                    //bOMComponent1.DescFlexField.PubDescSeg9 = comp.DescFlexField_PubDescSeg9;
                                }
                            }
                            //同料号同部件名导致的重复检查
                            var check = bommster.BOMComponents.Cast<BOMComponent>().GroupBy(t => t.Sequence).Where(t => t.Count() > 1);
                            var removeList = new List<BOMComponent>();
                            foreach (var bOMComponent in check)
                            {
                                foreach (var item in bOMComponent)
                                {
                                    if (!svpara.BOMComponents.Any(t => t.ItemMaster.ID == item.ItemMaster.ID && t.Sequence == item.Sequence && t.DescFlexField_PubDescSeg9 == item.DescFlexField.PubDescSeg9 && t.DescFlexField_PubDescSeg20 == item.DescFlexField.PubDescSeg20))
                                    {
                                        removeList.Add(item);
                                    }
                                }
                            }
                            foreach (var bOMComponent in removeList)
                            {
                                bommster.BOMComponents.Remove(bOMComponent);
                            }
                            session.Commit();
                        }
                        bomID = bommster.ID;
                    }
                    result.Data = bomID;
                    return result;
                }
                catch (Exception ex)
                {
                    LogManager.WriteLog(ex.Message + "\r\n" + ex.StackTrace, "All");
                    result.ResCode = 1;
                    result.ResMsg = ex.Message;
                    return result;
                }
            }
        }

        /// <summary>
        /// 设置料品有效性
        /// </summary>
        /// <param name="paras"></param>
        /// <returns></returns>
        public ApiResult<List<string>> SetItemEffective(List<SetItemEffectivePara> paras)
        {
            ApiResult<List<string>> result = new ApiResult<List<string>>();
            List<string> sucCode = new List<string>();
            LogManager.WriteLog(JsonConvert.SerializeObject(paras), "YunmaRequest");
            using (BPForEngine bp = new BPForEngine())
            {
                ContextDTO tdto = new ContextDTO();
                tdto.UserCode = _userCode;//取接口传入的用户编码
                tdto.EntCode = _entCode;//取接口传入的企业编码
                tdto.CultureName = "zh-CN";//固定
                tdto.OrgCode = _orgCode;//取接口传入的组织编码
                tdto.WriteToContext();

                try
                {
                    List<string> ItemCodeList = paras.Select(t => t.ItemCode).ToList();
                    var itemMasters = ItemMaster.Finder.FindAll($"Code in ({string.Join(",", ItemCodeList.Select(t => $"'{t}'"))})").Cast<ItemMaster>();
                    using (ISession session = Session.Open())
                    {
                        foreach (var para in paras)
                        {
                            var item = itemMasters.FirstOrDefault(t => t.Code == para.ItemCode);
                            if (item != null && item.Effective.IsEffective != para.IsEffective)
                            {
                                item.Effective.IsEffective = para.IsEffective;
                                sucCode.Add(para.ItemCode);
                            }
                        }
                        session.Commit();
                    }
                    result.Data = sucCode;
                    return result;
                }
                catch (Exception ex)
                {
                    LogManager.WriteLog($"{ex.Message}\r\n{ex.StackTrace}", "All");
                    result.ResCode = 1;
                    result.ResMsg = ex.Message;
                    return result;
                }
            }
        }

        /// <summary>
        /// 同步所有料品的形态属性(数据一致性同步)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ApiResult<string> SyncItemFormAttribute()
        {
            using (BPForEngine bp = new BPForEngine())
            {
                ContextDTO tdto = new ContextDTO();
                tdto.UserCode = _userCode;//取接口传入的用户编码
                tdto.EntCode = _entCode;//取接口传入的企业编码
                tdto.CultureName = "zh-CN";//固定
                tdto.OrgCode = _orgCode;//取接口传入的组织编码
                tdto.WriteToContext();
                ApiResult<string> rtn = new ApiResult<string>();
                JsonConfig config = new JsonConfig();
                string url = config.SelectToken("Yunma.URL");
                HttpHelper httpHelper = new HttpHelper();
                httpHelper.URL = url + "/openApi/info/upMaterielArchivesU9";
                var authDto = OpenAPIAuth.YunmaAuth();
                httpHelper.Token = authDto.token;
                List<ItemMaster> itemMasters = ItemMaster.Finder.FindAll("").Cast<ItemMaster>().ToList();
                StringBuilder sb = new StringBuilder();
                foreach (var item in itemMasters)
                {
                    string ifaName = UFIDA.U9.CBO.SCM.Item.ItemTypeAttributeEnum.EnumRes.GetResource(item.ItemFormAttribute.Name);
                    if (ifaName == "虚拟")
                        ifaName = "虚拟件";
                    var para = new
                    {
                        authDto.enterprise_id,
                        materiel_code = item.Code,
                        materiel_source_name = ifaName
                    };
                    httpHelper.Content = JsonConvert.SerializeObject(para);
                    JObject result = JObject.Parse(httpHelper.Request());
                    if (result.Value<bool>("success") == false)
                    {
                        sb.Append($"{item.Code} {result.Value<string>("msg")},");
                    }
                }
                if (sb.Length > 0)
                {
                    LogManager.WriteLog(sb.ToString(), "All");
                    rtn.ResCode = 1;
                    rtn.ResMsg = sb.ToString();
                    return rtn;
                }
                return rtn;
            }
        }

        /// <summary>
        /// 仓位配置表初始化
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ApiResult<string> BinConfigInit()
        {
            using (BPForEngine bp = new BPForEngine())
            {
                ContextDTO tdto = new ContextDTO();
                tdto.UserCode = _userCode;//取接口传入的用户编码
                tdto.EntCode = _entCode;//取接口传入的企业编码
                tdto.CultureName = "zh-CN";//固定
                tdto.OrgCode = _orgCode;//取接口传入的组织编码
                tdto.WriteToContext();
                var itemList = ItemMaster.Finder.FindAll($"DescFlexField.PrivateDescSeg10 != ''");
                ValueSetDef ywlxDef = ValueSetDef.FindByCode("YWLX");
                var ywlxs = DefineValue.Finder.FindAll($"Code in ('10','20','30','40','70') and ValueSetDef = {ywlxDef.ID}");
                ValueSetDef cwDef = ValueSetDef.FindByCode("MESCW");
                var cws = DefineValue.Finder.FindAll($"ValueSetDef = {cwDef.ID}").Cast<DefineValue>();
                int count = 0;
                var binConfigs = BinConfig.BinConfig.Finder.FindAll("").Cast<BinConfig.BinConfig>().ToList();
                Dictionary<string,bool> binConfigDict = new Dictionary<string,bool>();
                foreach ( var binConfig in binConfigs)
                {
                    string key = $"{binConfig.Itemmaster.ID}{binConfig.YWLX.ID}";
                    binConfigDict[key] = true ;
                }
                using (ISession session = Session.Open())
                {
                    foreach (var item in itemList)
                    {
                        foreach (var ywlx in ywlxs)
                        {
                            string key = $"{item.ID}{ywlx.ID}";
                            if (binConfigDict.ContainsKey(key))
                                continue;
                            var binconfig = BinConfig.BinConfig.Create();
                            count++;
                            binconfig.Itemmaster = item;
                            binconfig.YWLX = ywlx;
                            binconfig.Bin = cws.FirstOrDefault(t => t.Code == item.DescFlexField.PrivateDescSeg10);
                        }
                    }
                    session.Commit();
                }
                return new ApiResult<string>()
                {
                    Data = count.ToString(),
                };
            }


        }

        private static void ItemStateDefaultValue(UFIDA.U9.ISV.Item.ItemMasterDTOData im)
        {
            switch (im.ItemFormAttribute)
            {
                case 0:
                    ItemStateDefaultValue(im, false, true, true, true, false, true, true, false, false, false, false, false, true, false);
                    break;
                case 1:
                    ItemStateDefaultValue(im, false, true, true, false, false, true, true, false, false, false, false, false, false, false);
                    break;
                case 2:
                    ItemStateDefaultValue(im, true, true, true, true, true, true, true, true, true, true, true, true, true, true);
                    break;
                case 3:
                    ItemStateDefaultValue(im, false, false, false, false, false, true, true, false, false, false, false, false, false, false);
                    break;
                case 4:
                    ItemStateDefaultValue(im, true, true, true, true, true, true, true, true, true, true, true, true, true, true);
                    break;
                case 5:
                    ItemStateDefaultValue(im, true, true, false, false, false, false, false, false, false, false, false, false, false, false);
                    break;
                case 6:
                    ItemStateDefaultValue(im, false, false, false, false, false, true, true, true, true, true, true, true, true, false);
                    break;
                case 7:
                    ItemStateDefaultValue(im, false, false, false, false, false, true, true, false, false, false, false, false, false, false);
                    break;
                case 8:
                    ItemStateDefaultValue(im, false, false, false, false, false, true, true, false, false, false, false, false, false, false);
                    break;
                case 9:
                    ItemStateDefaultValue(im, true, true, true, false, true, true, true, true, true, true, true, true, true, true);
                    break;
                case 10:
                    ItemStateDefaultValue(im, true, true, true, true, true, true, true, true, true, true, true, true, true, true);
                    break;
                case 11:
                    ItemStateDefaultValue(im, true, true, true, true, false, true, true, true, true, true, true, true, true, true);
                    break;
                case 12:
                    ItemStateDefaultValue(im, false, true, true, true, false, true, true, false, false, false, false, false, false, false);
                    break;
                case 13:
                    ItemStateDefaultValue(im, false, false, false, true, false, true, true, false, false, false, false, false, false, false);
                    break;
                case 14:
                    ItemStateDefaultValue(im, true, true, false, false, false, false, false, false, false, true, true, true, true, true);
                    break;
                case 15:
                    ItemStateDefaultValue(im, true, true, true, false, false, false, false, true, true, true, true, true, true, true);
                    break;
                case 16:
                    ItemStateDefaultValue(im, true, true, true, false, false, false, false, false, false, true, true, false, false, true);
                    break;
                case 17:
                    ItemStateDefaultValue(im, false, true, true, false, false, false, false, false, false, false, false, false, false, false);
                    break;
                case 18:
                    ItemStateDefaultValue(im, true, true, true, false, false, false, false, false, false, true, true, false, false, false);
                    break;
                case 19:
                    ItemStateDefaultValue(im, true, true, true, false, false, false, false, true, true, true, true, true, true, true);
                    break;
                case 20:
                    ItemStateDefaultValue(im, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
                    break;
                case 21:
                    ItemStateDefaultValue(im, true, true, true, true, true, true, true, true, true, true, true, true, true, true);
                    break;
                case 22:
                    ItemStateDefaultValue(im, true, true, true, false, false, false, false, false, false, true, true, false, false, false);
                    break;
            }
        }
        private static void ItemStateDefaultValue(UFIDA.U9.ISV.Item.ItemMasterDTOData im, bool isInv, bool isPur, bool isSale, bool isMfg, bool isOutsideOperationEnable, bool isMrp, bool isBOM, bool isResv, bool isATP, bool isInvPlan, bool isAva, bool isLot, bool isSn, bool isVMI)
        {
            if (!isInv && im.IsInventoryEnable)
            {
                im.IsInventoryEnable = false;
            }
            if (!isPur && im.IsPurchaseEnable)
            {
                im.IsPurchaseEnable = false;
            }
            if (!isSale && im.IsSalesEnable)
            {
                im.IsSalesEnable = false;
            }
            if (!isMfg && im.IsBuildEnable)
            {
                im.IsBuildEnable = false;
            }
            if (!isOutsideOperationEnable && im.IsOutsideOperationEnable)
            {
                im.IsOutsideOperationEnable = false;
            }
            if (!isMrp && im.IsMRPEnable)
            {
                im.IsMRPEnable = false;
            }
            if (!isBOM && im.IsBOMEnable)
            {
                im.IsBOMEnable = false;
            }
            if (!isResv && im.InventoryInfo.IsReservable)
            {
                im.InventoryInfo.IsReservable = false;
            }
            if (!isATP && im.SaleInfo.IsATPCheck)
            {
                im.SaleInfo.IsATPCheck = false;
            }
            if (!isLot && im.InventoryInfo.LotParam != null)
            {
                im.InventoryInfo.LotParam = null;
            }
            if (!isSn && im.InventoryInfo.SnParam != null)
            {
                im.InventoryInfo.SnParam = null;
            }
            if (isVMI && !im.IsVMIEnable)
            {
                im.IsVMIEnable = true;
            }
        }
    }
}
